home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 28
/
Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso
/
Aminet
/
game
/
board
/
Crafty-15.19.lha
/
crafty-15.19
/
src
/
make.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-09-13
|
23KB
|
663 lines
#include <stdio.h>
#include <stdlib.h>
#include "chess.h"
#include "data.h"
/* last modified 03/11/98 */
/*
********************************************************************************
* *
* MakeMove() is responsible for updating the position database whenever a *
* piece is moved. it performs the following operations: (1) update the *
* board structure itself by moving the piece and removing any captured *
* piece. (2) update the hash keys. (3) update material counts. (4) update *
* castling status. (5) update number of moves since last reversible move. *
* *
********************************************************************************
*/
void MakeMove(TREE *tree, int ply, int move, int wtm)
{
register int piece, from, to, captured, promote;
BITBOARD bit_move;
/*
----------------------------------------------------------
| |
| first, clear the EnPassant_Target bit-mask. moving a |
| pawn two ranks will set it later in MakeMove(). |
| |
----------------------------------------------------------
*/
#if defined(DEBUG)
ValidatePosition(tree,ply,move,"MakeMove(1)");
#endif
tree->position[ply+1]=tree->position[ply];
tree->save_hash_key[ply]=HashKey;
tree->save_pawn_hash_key[ply]=PawnHashKey;
if (EnPassant(ply+1)) {
HashEP(EnPassant(ply+1),HashKey);
EnPassant(ply+1)=0;
}
Rule50Moves(ply+1)++;
/*
----------------------------------------------------------
| |
| now do the piece-specific things by calling the |
| appropriate routine. |
| |
----------------------------------------------------------
*/
piece=Piece(move);
from=From(move);
to=To(move);
captured=Captured(move);
promote=Promote(move);
MakePieceMove:
ClearRL90(from,OccupiedRL90);
ClearRL45(from,OccupiedRL45);
ClearRR45(from,OccupiedRR45);
SetRL90(to,OccupiedRL90);
SetRL45(to,OccupiedRL45);
SetRR45(to,OccupiedRR45);
bit_move=Or(set_mask[from],set_mask[to]);
PieceOnSquare(from)=0;
switch (piece) {
/*
********************************************************************************
* *
* make pawn moves. there are two special cases: (a) enpassant captures *
* where the captured pawn is not on the "to" square and must be removed in *
* a different way, and (2) pawn promotions (where the "Promote" variable *
* is non-zero) requires updating the appropriate bit boards since we are *
* creating a new piece. *
* *
********************************************************************************
*/
case pawn:
if (wtm) {
ClearSet(bit_move,WhitePawns);
ClearSet(bit_move,WhitePieces);
HashPW(from,HashKey);
HashPW32(from,PawnHashKey);
HashPW(to,HashKey);
HashPW32(to,PawnHashKey);
PieceOnSquare(to)=pawn;
if (captured == 1) {
if(!And(BlackPawns,set_mask[to])) {
ClearRL90(to-8,OccupiedRL90);
ClearRL45(to-8,OccupiedRL45);
ClearRR45(to-8,OccupiedRR45);
Clear(to-8,BlackPawns);
Clear(to-8,BlackPieces);
HashPB(to-8,HashKey);
HashPB32(to-8,PawnHashKey);
PieceOnSquare(to-8)=0;
Material+=PAWN_VALUE;
TotalBlackPawns--;
TotalPieces--;
captured=0;
}
}
/*
--------------------------------------------------------------------
| |
| if this is a pawn promotion, remove the pawn from the counts |
| then update the correct piece board to reflect the piece just |
| created. |
| |
--------------------------------------------------------------------
*/
if (promote) {
TotalWhitePawns--;
Material-=PAWN_VALUE;
Clear(to,WhitePawns);
HashPW(to,HashKey);
HashPW32(to,PawnHashKey);
switch (promote) {
case knight:
Set(to,WhiteKnights);
HashNW(to,HashKey);
PieceOnSquare(to)=knight;
TotalWhitePieces+=knight_v;
WhiteMinors++;
Material+=KNIGHT_VALUE;
break;
case bishop:
Set(to,WhiteBishops);
Set(to,BishopsQueens);
HashBW(to,HashKey);
PieceOnSquare(to)=bishop;
TotalWhitePieces+=bishop_v;
WhiteMinors++;
Material+=BISHOP_VALUE;
break;
case rook:
Set(to,WhiteRooks);
Set(to,RooksQueens);
HashRW(to,HashKey);
PieceOnSquare(to)=rook;
TotalWhitePieces+=rook_v;
WhiteMajors++;
Material+=ROOK_VALUE;
break;
case queen:
Set(to,WhiteQueens);
Set(to,BishopsQueens);
Set(to,RooksQueens);
HashQW(to,HashKey);
PieceOnSquare(to)=queen;
TotalWhitePieces+=queen_v;
WhiteMajors+=2;
Material+=QUEEN_VALUE;
break;
}
}
else
if (((to-from) == 16) && And(mask_eptest[to],BlackPawns)) {
EnPassant(ply+1)=to-8;
HashEP(to-8,HashKey);
}
}
else {
ClearSet(bit_move,BlackPawns);
ClearSet(bit_move,BlackPieces);
HashPB(from,HashKey);
HashPB32(from,PawnHashKey);
HashPB(to,HashKey);
HashPB32(to,PawnHashKey);
PieceOnSquare(to)=-pawn;
if (captured == 1) {
if(!And(WhitePawns,set_mask[to])) {
ClearRL90(to+8,OccupiedRL90);
ClearRL45(to+8,OccupiedRL45);
ClearRR45(to+8,OccupiedRR45);
Clear(to+8,WhitePawns);
Clear(to+8,WhitePieces);
HashPW(to+8,HashKey);
HashPW32(to+8,PawnHashKey);
PieceOnSquare(to+8)=0;
Material-=PAWN_VALUE;
TotalWhitePawns--;
TotalPieces--;
captured=0;
}
}
/*
--------------------------------------------------------------------
| |
| if this is a pawn promotion, remove the pawn from the counts |
| then update the correct piece board to reflect the piece just |
| created. |
| |
--------------------------------------------------------------------
*/
if (promote) {
TotalBlackPawns--;
Material+=PAWN_VALUE;
Clear(to,BlackPawns);
HashPB(to,HashKey);
HashPB32(to,PawnHashKey);
switch (promote) {
case knight:
Set(to,BlackKnights);
HashNB(to,HashKey);
PieceOnSquare(to)=-knight;
TotalBlackPieces+=knight_v;
BlackMinors++;
Material-=KNIGHT_VALUE;
break;
case bishop:
Set(to,BlackBishops);
Set(to,BishopsQueens);
HashBB(to,HashKey);
PieceOnSquare(to)=-bishop;
TotalBlackPieces+=bishop_v;
BlackMinors++;
Material-=BISHOP_VALUE;
break;
case rook:
Set(to,BlackRooks);
Set(to,RooksQueens);
HashRB(to,HashKey);
PieceOnSquare(to)=-rook;
TotalBlackPieces+=rook_v;
BlackMajors++;
Material-=ROOK_VALUE;
break;
case queen:
Set(to,BlackQueens);
Set(to,BishopsQueens);
Set(to,RooksQueens);
HashQB(to,HashKey);
PieceOnSquare(to)=-quee